﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Imgur.Net.JSON;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Imgur.Net
{
    /// <summary>
    /// Transfer object that represents the Imgur album info structure.
    /// </summary>
    [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
    public class AlbumInfo
    {
        /// <summary>
        /// Used for automatic serialization and deserialization only.
        /// </summary>
        [JsonConstructor]
        protected AlbumInfo()
        {
            
        }

        /// <summary>
        /// Constructs an instance of this object. Fields which are members of this class but are not passed in via parameters will be left to their default
        /// values. Typicalls this will be one of null, 0, long.MinValue, or null depending on data type.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="timeStamp"></param>
        /// <param name="layout"></param>
        /// <param name="views"></param>
        /// <param name="link"></param>
        /// <param name="deleteHash"></param>
        public AlbumInfo(string id, string title, string description, DateTime timeStamp, LayoutStyle layout, long views, string link, string deleteHash)
            : this( id, title, description, timeStamp, null, 0, 0, null, Net.PrivacyLevel.Public, layout, views, link, null, null, null, null, 0, deleteHash, 0 )
        {
        }

        /// <summary>
        /// Constructs an instance of this object. Fields which are members of this class but are not passed in via parameters will be left to their default
        /// values. Typicalls this will be one of null, 0, long.MinValue, or null depending on data type.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="albumCoverId"></param>
        /// <param name="timeStamp"></param>
        /// <param name="albumCoverWidth"></param>
        /// <param name="albumCoverHeight"></param>
        /// <param name="accountUrl"></param>
        /// <param name="privacyLevel"></param>
        /// <param name="layout"></param>
        /// <param name="views"></param>
        /// <param name="link"></param>
        /// <param name="isFavorite"></param>
        /// <param name="isNsfw"></param>
        /// <param name="section"></param>
        /// <param name="imagesCount"></param>
        /// <param name="deleteHash"></param>
        /// <param name="order"></param>
        public AlbumInfo(string id, string title, string description, DateTime timeStamp, string albumCoverId, int albumCoverWidth, int albumCoverHeight, string accountUrl, PrivacyLevel privacyLevel, LayoutStyle layout, long views, string link, bool? isFavorite, bool? isNsfw, string section, int imagesCount, string deleteHash, int order)
            : this( id, title, description, timeStamp, albumCoverId, albumCoverWidth, albumCoverHeight, accountUrl, privacyLevel, layout, views, link, isFavorite, isNsfw, section, null, imagesCount, deleteHash, order )
        {
            
        }

        /// <summary>
        /// Constructs an instance of this object. Fields which are members of this class but are not passed in via parameters will be left to their default
        /// values. Typicalls this will be one of null, 0, long.MinValue, or null depending on data type.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="timeStamp"></param>
        /// <param name="albumCoverId"></param>
        /// <param name="albumCoverWidth"></param>
        /// <param name="albumCoverHeight"></param>
        /// <param name="accountUrl"></param>
        /// <param name="privacyLevel"></param>
        /// <param name="layout"></param>
        /// <param name="views"></param>
        /// <param name="link"></param>
        /// <param name="isFavorite"></param>
        /// <param name="isNsfw"></param>
        /// <param name="section"></param>
        /// <param name="images"></param>
        /// <param name="imagesCount"></param>
        /// <param name="deleteHash"></param>
        /// <param name="order"></param>
        public AlbumInfo(string id, string title, string description, DateTime timeStamp, string albumCoverId, int albumCoverWidth, int albumCoverHeight, string accountUrl, PrivacyLevel privacyLevel, LayoutStyle layout, long views, string link, bool? isFavorite, bool? isNsfw, string section, List<ImageInfo> images, int imagesCount, string deleteHash, int order)
        {
            Id = id;
            Title = title;
            Description = description;
            TimeStamp = timeStamp;
            AlbumCoverId = albumCoverId;
            AlbumCoverWidth = albumCoverWidth;
            AlbumCoverHeight = albumCoverHeight;
            AccountUrl = accountUrl;
            PrivacyLevel = privacyLevel;
            Layout = layout;
            Views = views;
            Link = link;
            IsFavorite = isFavorite;
            IsNSFW = isNsfw;
            Section = section;
            Images = images;
            ImagesCount = imagesCount;
            DeleteHash = deleteHash;
            Order = order;
        }

        /// <summary>
        /// The id of the album. 
        /// </summary>
        /// <remarks>Represented by the "<b>id</b>" JSON value</remarks>
        [JsonProperty]
        public string Id { get; private set; }

        /// <summary>
        /// The title of the album as given by the uploader, if any.
        /// </summary>
        /// <remarks>Represented by the "<b>title</b>" JSON value</remarks>
        [JsonProperty("title")]
        public string Title { get; private set; }

        /// <summary>
        /// The description of the album as given by the uploader, if any.
        /// </summary>
        /// <remarks>Represented by the "<b>description</b>" JSON value</remarks>
        [JsonProperty("description")]
        public string Description { get; private set; }

        /// <summary>
        /// The timestamp of the album being inserted into the gallery.
        /// </summary>
        /// <remarks>Represented by the "<b>datetime</b>" JSON value</remarks>
        [JsonProperty("datetime")]
        [JsonConverter(typeof(EpochDateTimeConverter))]
        public DateTime TimeStamp { get; private set; }

        /// <summary>
        /// The Image ID of the album cover image, if any.
        /// </summary>
        /// <remarks>Represented by the "<b>cover</b>" JSON value</remarks>
        [JsonProperty("cover")]
        public string AlbumCoverId { get; private set; }

        /// <summary>
        /// The pixel width of the cover image.
        /// </summary>
        /// <remarks>Represented by the "<b>cover_width</b>" JSON value</remarks>
        [JsonProperty("cover_width", NullValueHandling = NullValueHandling.Ignore)]
        public int AlbumCoverWidth { get; private set; }

        /// <summary>
        /// The pixel height of the cover image.
        /// </summary>
        /// <remarks>Represented by the "<b>cover_height</b>" JSON value</remarks>
        [JsonProperty("cover_height", NullValueHandling = NullValueHandling.Ignore)]
        public int AlbumCoverHeight { get; private set; }

        /// <summary>
        /// The URL to the Imgur account that created the album, if available.
        /// </summary>
        /// <remarks>Represented by the "<b>account_url</b>" JSON value</remarks>
        [JsonProperty("account_url")]
        public string AccountUrl { get; private set; }

        /// <summary>
        /// The privacy level of the album.
        /// </summary>
        /// <remarks>Represented by the "<b>privacy</b>" JSON value</remarks>
        [JsonProperty("privacy")]
        [JsonConverter(typeof(StringEnumConverter))]
        public PrivacyLevel PrivacyLevel { get; private set; }

        /// <summary>
        /// The layout style of the album.
        /// </summary>
        /// <remarks>Represented by the "<b>layout</b>" JSON value</remarks>
        [JsonProperty("layout")]
        [JsonConverter(typeof(StringEnumConverter))]
        public LayoutStyle Layout { get; private set; }

        /// <summary>
        /// The number of views this album has received since being uploaded.
        /// </summary>
        /// <remarks>Represented by the "<b>views</b>" JSON value</remarks>
        [JsonProperty]
        public long Views { get; private set; }

        /// <summary>
        /// The URL link to this album.
        /// </summary>
        /// <remarks>Represented by the "<b>link</b>" JSON value</remarks>
        [JsonProperty]
        public string Link { get; private set; }

        /// <summary>
        /// Flag denoting that this is a favorite of the current user. False if the current user is anonymous.
        /// </summary>
        /// <remarks>Represented by the "<b>favorite</b>" JSON value</remarks>
        [JsonProperty("favorite",NullValueHandling = NullValueHandling.Ignore)]
        public bool? IsFavorite { get; private set; }

        /// <summary>
        /// Flag denoting that this album is Not Safe For Work (nsfw).
        /// </summary>
        /// <remarks>Represented by the "<b>nsfw</b>" JSON value</remarks>
        [JsonProperty("nsfw", NullValueHandling = NullValueHandling.Ignore)]
        public bool? IsNSFW { get; private set; }

        /// <summary>
        /// The section classification for this album. Section is assigned by Imgur to help categorize albums automatically.
        /// </summary>
        /// <remarks>Represented by the "<b>section</b>" JSON value</remarks>
        [JsonProperty]
        public string Section { get; private set; }

        /// <summary>
        /// The order number of this album on the owner's album page. Defaults to 0.
        /// </summary>
        /// <remarks>Represented by the "<b>order</b>" JSON value</remarks>
        [JsonProperty("order")]
        public int Order { get; private set; }

        /// <summary>
        /// The deletehash key for this image.
        /// </summary>
        /// <remarks>Represented by the "<b>deletehash</b>" JSON value</remarks>
        [JsonProperty("deletehash")]
        public string DeleteHash { get; private set; }

        /// <summary>
        /// The number of images in this album.
        /// </summary>
        /// <remarks>Represented by the "<b>images_count</b>" JSON value</remarks>
        [JsonProperty("images_count")]
        public int ImagesCount { get; private set; }
        
        /// <summary>
        /// The image info objects for images in this album.
        /// </summary>
        /// <remarks>Represented by the "<b>images</b>" JSON value</remarks>
        [JsonProperty("images")]
        public List<ImageInfo> Images { get; private set; }
    }
}
